﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Transactions;

namespace ThinkNet.ORM
{
    public class ORM
    {
        #region 新增
        /// <summary>
        /// 数据插入
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t">数据实体</param>
        /// <param name="IsReturnId">是否为返回自增ID（true = 是自增ID, false = 不是自增ID）</param>   
        /// <returns></returns>
        public static int Insert<T>(T t, bool IsReturnId = false)
        {
            return Context.DataBase.Instance.Insert(t, IsReturnId);
        }

        public static long Insert64<T>(T t, bool IsReturnId = false)
        {
            return Context.DataBase.Instance.Insert64(t, IsReturnId);
        }

        /// <summary>
        /// 数据批量插入
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t">数据实体集合</param>
        /// <returns>受影响行数</returns>
        public static int InsertBat<T>(List<T> t)
        {
            return Context.DataBase.Instance.InsertBat(t);
        }
        #endregion

        #region 修改
        /// <summary>
        /// 数据修改
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t">数据实体（只传入需要修改的字段即可,主键ID必填）</param>
        /// <returns></returns>
        public static int Update<T>(T t)
        {
            return Context.DataBase.Instance.Update(t);
        }

        /// <summary>
        /// 数据修改（按条件修改）
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t">数据实体（只传入需要修改的字段即可）</param>
        /// <param name="bizExp">修改条件（兰姆达表达式）</param>
        /// <returns></returns>
        public static int Update<T>(T t, Expression<Func<IQueryable<T>, IQueryable<T>>> bizExp)
        {
            return Context.DataBase.Instance.Update(t, bizExp);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t">数据实体集合（只传入需要修改的字段即可）</param>
        /// <returns></returns>
        public static int UpdateBat<T>(List<T> t)
        {
            return Context.DataBase.Instance.UpdateBat(t);
        }
        #endregion

        #region 删除
        /// <summary>
        /// 数据物理删除
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t">数据实体（只传入需要删除的数据ID即可）</param>    
        /// <returns></returns>
        public static int Delete<T>(T t)
        {
            return Context.DataBase.Instance.Delete(t);
        }

        /// <summary>
        /// 数据物理删除（按条件删除）
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t">数据实体</param>
        /// <param name="bizExp">删除条件（兰姆达表达式）</param>     
        /// <returns></returns>
        public static int Delete<T>(T t, Expression<Func<IQueryable<T>, IQueryable<T>>> bizExp)
        {
            return Context.DataBase.Instance.Delete(t, bizExp);
        }

        /// <summary>
        /// 数据逻辑删除
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t">数据实体（只传入需要删除的数据ID即可）</param>
        /// <returns></returns>
        public static int LogicalDelete<T>(T t)
        {
            return Context.DataBase.Instance.LogicalDelete(t);
        }

        /// <summary>
        /// 数据逻辑删除（按条件删除）
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t">数据实体</param>
        /// <param name="bizExp">删除条件（兰姆达表达式）</param>   
        /// <returns></returns>
        public static int LogicalDelete<T>(T t, Expression<Func<IQueryable<T>, IQueryable<T>>> bizExp)
        {
            return Context.DataBase.Instance.LogicalDelete(t, bizExp);
        }
        #endregion

        #region 实体查询
        /// <summary>
        /// 查询数据（通过ID查询数据对象）
        /// </summary>
        /// <typeparam name="T">操作的表名</typeparam>
        /// <param name="id">所要查询的ID值</param>
        /// <param name="showCols">所需查询的列（默认为：全部列, 例："col1,col2,col3"）</param>
        /// <param name="nolock">查询锁（默认为：不使用锁）</param>        
        /// <returns>T</returns>
        public static T Get<T>(string id, string showCols = "*", bool nolock = true)
        {
            return Context.DataBase.Instance.Get<T>(id, showCols, nolock);
        }

        /// <summary>
        /// 查询数据（通过ID查询数据对象）
        /// </summary>
        /// <typeparam name="T">操作的表名</typeparam>
        /// <typeparam name="NT">映射到业务Entity</typeparam>
        /// <param name="id">所要查询的ID值</param>
        /// <param name="showCols">所需查询的列（默认为：全部列, 例："col1,col2,col3"）</param>
        /// <param name="nolock">查询锁（默认为：不使用锁）</param>        
        /// <returns>NT</returns>
        public static NT Get<T, NT>(string id, string showCols = "*", bool nolock = true)
        {
            return Context.DataBase.Instance.Get<T, NT>(id, showCols, nolock);
        }
        #endregion

        #region 列表查询
        /// <summary>
        /// 查询数据（通过条件查询数据列表）
        /// </summary>
        /// <typeparam name="T">操作的表名</typeparam>
        /// <param name="bizExp">查询条件（兰姆达表达式）</param>
        /// <param name="showCols">所需查询的列（默认为：全部列, 例："col1,col2,col3"）</param>
        /// <param name="nolock">查询锁（默认为：不使用锁）</param>        
        /// <returns>IList<T></returns>
        public static IList<T> Get<T>(Expression<Func<IQueryable<T>, IQueryable<T>>> bizExp, string showCols = "*", bool nolock = true)
        {
            return Context.DataBase.Instance.Get(bizExp, showCols, nolock);
        }

        /// <summary>
        /// 查询数据（通过条件查询数据列表）
        /// </summary>
        /// <typeparam name="T">操作的表名</typeparam>
        /// <typeparam name="NT">映射到业务Entity</typeparam>
        /// <param name="bizExp">查询条件（兰姆达表达式）</param>
        /// <param name="showCols">所需查询的列（默认为：全部列, 例："col1,col2,col3"）</param>
        /// <param name="nolock">查询锁（默认为：不使用锁）</param>        
        /// <returns>IList<NT></returns>
        public static IList<NT> Get<T, NT>(Expression<Func<IQueryable<T>, IQueryable<T>>> bizExp, string showCols = "*", bool nolock = true)
        {
            return Context.DataBase.Instance.Get<T, NT>(bizExp, showCols, nolock);
        }

        /// <summary>
        /// 查询数据（通过条件查询数据列表）
        /// </summary>
        /// <typeparam name="T">操作的表名</typeparam>
        /// <param name="where">查询条件（例：where mark > 0）</param>
        /// <param name="orderBy">排序（例：order by CreateDate desc）</param>
        /// <param name="showCols">所需查询的列（默认为：全部列, 例："col1,col2,col3"）</param>
        /// <param name="param">参数</param>
        /// <param name="nolock">查询锁（默认为：不使用锁）</param>        
        /// <returns>IList<T></returns>
        public static IList<T> GetWhere<T>(string where, string orderBy, string showCols = "*", object param = null, bool nolock = true)
        {
            return Context.DataBase.Instance.GetWhere<T>(where, orderBy, showCols, param, nolock);
        }

        /// <summary>
        /// 查询数据（通过条件查询数据列表）
        /// </summary>
        /// <typeparam name="T">操作的表名</typeparam>
        /// <typeparam name="NT">映射到业务Entity</typeparam>
        /// <param name="where">查询条件（例：where mark > 0）</param>
        /// <param name="orderBy">排序（例：order by CreateDate desc）</param>
        /// <param name="showCols">所需查询的列（默认为：全部列, 例："col1,col2,col3"）</param>
        /// <param name="param">参数</param>
        /// <param name="nolock">查询锁（默认为：不使用锁）</param>        
        /// <returns>IList<NT></returns>
        public static IList<NT> GetWhere<T, NT>(string where, string orderBy, string showCols = "*", object param = null, bool nolock = true)
        {
            return Context.DataBase.Instance.GetWhere<T, NT>(where, orderBy, showCols, param, nolock);
        }
        #endregion

        #region 分页查询
        /// <summary>
        /// 分页查询数据
        /// </summary>
        /// <typeparam name="T">操作的表名</typeparam>
        /// <param name="bizExp">查询条件（兰姆达表达式）</param>
        /// <param name="pageIndex">第几页（第一页为：1）</param>
        /// <param name="pageSize">页行数</param>
        /// <param name="showCols">所需查询的列（默认为：全部列, 例："col1,col2,col3"）</param>
        /// <param name="nolock">查询锁（默认为：不使用锁）</param>        
        /// <returns></returns>
        public static MPageData<T> Get<T>(Expression<Func<IQueryable<T>, IQueryable<T>>> bizExp, int pageIndex, int pageSize, string showCols = "*", bool nolock = true, ESqlVersion sqlVersion = ESqlVersion.SqlServer2012)
        {
            return Context.DataBase.Instance.Get(bizExp, pageIndex, pageSize, showCols, nolock, sqlVersion);
        }

        /// <summary>
        /// 分页查询数据
        /// </summary>
        /// <typeparam name="T">操作的表名</typeparam>
        /// <typeparam name="NT">映射到业务Entity</typeparam>
        /// <param name="bizExp">查询条件（兰姆达表达式）</param>
        /// <param name="pageIndex">第几页（第一页为：1）</param>
        /// <param name="pageSize">页行数</param>
        /// <param name="showCols">所需查询的列（默认为：全部列, 例："col1,col2,col3"）</param>
        /// <param name="nolock">查询锁（默认为：不使用锁）</param>        
        /// <returns></returns>
        public static MPageData<NT> Get<T, NT>(Expression<Func<IQueryable<T>, IQueryable<T>>> bizExp, int pageIndex, int pageSize, string showCols = "*", bool nolock = true, ESqlVersion sqlVersion = ESqlVersion.SqlServer2012)
        {
            return Context.DataBase.Instance.Get<T, NT>(bizExp, pageIndex, pageSize, showCols, nolock, sqlVersion);
        }

        /// <summary>
        /// 分页查询数据
        /// </summary>
        /// <typeparam name="T">操作的表名</typeparam>
        /// <param name="where">查询条件（例：where mark > 0）</param>
        /// <param name="orderBy">排序（例：order by CreateDate desc）</param>
        /// <param name="pageIndex">第几页（第一页为：1）</param>
        /// <param name="pageSize">页行数</param>
        /// <param name="showCols">所需查询的列（默认为：全部列, 例："col1,col2,col3"）</param>
        /// <param name="param">参数</param>
        /// <param name="nolock">查询锁（默认为：不使用锁）</param>        
        /// <returns></returns>
        public static MPageData<T> GetWhere<T>(string where, string orderBy, int pageIndex, int pageSize, string showCols = "*", object param = null, bool nolock = true, ESqlVersion sqlVersion = ESqlVersion.SqlServer2012)
        {
            return Context.DataBase.Instance.GetWhere<T>(where, orderBy, pageIndex, pageSize, showCols, param, nolock, sqlVersion);
        }

        /// <summary>
        /// 分页查询数据
        /// </summary>
        /// <typeparam name="T">操作的表名</typeparam>
        /// <typeparam name="NT">映射到业务Entity</typeparam>
        /// <param name="where">查询条件（例：where mark > 0）</param>
        /// <param name="orderBy">排序（例：order by CreateDate desc）</param>
        /// <param name="pageIndex">第几页（第一页为：1）</param>
        /// <param name="pageSize">页行数</param>
        /// <param name="showCols">所需查询的列（默认为：全部列, 例："col1,col2,col3"）</param>
        /// <param name="param">参数</param>
        /// <param name="nolock">查询锁（默认为：不使用锁）</param>        
        /// <returns></returns>
        public static MPageData<NT> GetWhere<T, NT>(string where, string orderBy, int pageIndex, int pageSize, string showCols = "*", object param = null, bool nolock = true, ESqlVersion sqlVersion = ESqlVersion.SqlServer2012)
        {
            return Context.DataBase.Instance.GetWhere<T, NT>(where, orderBy, pageIndex, pageSize, showCols, param, nolock, sqlVersion);
        }
        #endregion

        #region 事务
        /// <summary>
        /// 事务处理
        /// </summary>
        /// <returns></returns>
        public static TransactionScope TransMaster(System.Transactions.IsolationLevel isolationLevel = System.Transactions.IsolationLevel.Serializable)
        {
            return Context.DataBase.Instance.TransMaster(isolationLevel);
        }
        #endregion

        #region Sql查询
        /// <summary>
        /// 执行存储过程
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="procName">存储过程名称</param>
        /// <param name="param">参数</param>
        /// <returns></returns>
        public static IList<T> RunProc<T>(string procName, object param = null)
        {
            return Context.DataBase.Instance.RunProc<T>(procName, param);
        }

        /// <summary>
        /// 执行SQL语句
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="procName">存储过程名称</param>
        /// <param name="param">参数</param>
        /// <returns></returns>
        public static IList<T> RunSql<T>(string sql, object param = null)
        {
            return Context.DataBase.Instance.RunSql<T>(sql, param);
        }

        public static MPageData<T> RunSql<T>(string sql, string orderBy, int pageIndex, int pageSize, object param = null, ESqlVersion sqlVersion = ESqlVersion.SqlServer2012)
        {
            return Context.DataBase.Instance.RunSql<T>(sql, orderBy, pageIndex, pageSize, param, sqlVersion);
        }
        #endregion

        #region 统计
        /// <summary>
        /// 统计（累加）
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="bizExp">查询条件（兰姆达表达式）</param>
        /// <param name="SumCol">累加的字段名</param>
        /// <param name="nolock">查询锁（默认为：不使用锁）</param>        
        /// <returns></returns>
        public static decimal Sum<T>(Expression<Func<IQueryable<T>, IQueryable<T>>> bizExp, string SumCol, bool nolock = true)
        {
            return Context.DataBase.Instance.Sum(bizExp, SumCol, nolock);
        }

        /// <summary>
        /// 统计（计数）
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="bizExp">查询条件（兰姆达表达式）</param>
        /// <param name="nolock">查询锁（默认为：不使用锁）</param>        
        /// <returns></returns>
        public static int Count<T>(Expression<Func<IQueryable<T>, IQueryable<T>>> bizExp, bool nolock = true)
        {
            return Context.DataBase.Instance.Count(bizExp, nolock);
        }
        #endregion
    }
}
